package com.gls.security.server.authorization.service.impl;

import com.gls.security.server.authorization.jpa.entity.Client;
import com.gls.security.server.authorization.jpa.repository.ClientRepository;
import com.gls.security.server.authorization.service.ClientService;
import com.gls.security.server.authorization.translator.ClientTranslator;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * @author lizhiyong
 */
@Service
@Primary
@Transactional(rollbackFor = Exception.class)
public class ClientServiceImpl implements ClientService, InitializingBean {

    private static final Set<String> DEFAULT_GRANT_TYPES = new HashSet<>(Arrays.asList("authorization_code", "password", "client_credentials", "implicit", "refresh_token"));

    private static final Set<String> DEFAULT_SCOPE = new HashSet<>(Arrays.asList("all", "read"));

    @Value("${security.oauth2.client.client-id}")
    private String defaultClientId;

    @Value("${security.oauth2.client.client-secret}")
    private String defaultClientSecret;

    @Autowired
    private ClientRepository clientRepository;

    @Autowired
    private ClientTranslator clientTranslator;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
        Client client = clientRepository.findByClientId(clientId);
        ClientDetails clientDetails = clientTranslator.translator(client);
        return clientDetails;
    }

    @Override
    public void afterPropertiesSet() {
        String clientId = defaultClientId;
        Client client = clientRepository.findByClientId(clientId);
        if (client == null) {
            client = new Client();
            client.setClientId(clientId);
            client.setClientSecret(passwordEncoder.encode(defaultClientSecret));
            client.setAuthorizedGrantTypes(DEFAULT_GRANT_TYPES);
            client.setScope(DEFAULT_SCOPE);
            client.setAutoApproveScopes(DEFAULT_SCOPE);
            clientRepository.save(client);
        }
    }
}
